﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Sunny.UI;

namespace SmartMotion.Core.Tools
{
    public partial class FrmConstructor : UIForm
    {
        #region 私有字段

        private Constructor _constructor;
        private List<Type> _types;
        private ConstructorInfo[] _constructorInfos;
        private List<string> _paraTypes;
        private List<string> _paraNames;

        #endregion
        public FrmConstructor(Constructor constructor)
        {
            _constructor = constructor;
            _paraTypes = new List<string>();
            _paraNames = new List<string>();
            InitializeComponent();
        }

        private void FrmConstructor_Load(object sender, EventArgs e)
        {
            RefreshDll(false);
        }

        private void RefreshDll(bool loadAll = true)
        {
            var files = Directory.GetFiles(Environment.CurrentDirectory, "*.dll");
            lstDll.Items.Clear();
            foreach (var file in files)
            {
                try
                {
                    var types = ReflectAble.GetTypes(file, loadAll);
                    if (types.Count > 0) lstDll.Items.Add(Path.GetFileName(file));
                }
                catch (Exception exception)
                {
                    Console.WriteLine(exception);
                }
            }

            #region 加载上一次的配置

            int index = lstDll.Items.IndexOf(_constructor.Dll);
            lstDll.SelectedIndex = index;

            foreach (var type in _types)
            {
                if (type.FullName==_constructor.TypeName)
                {
                    lstTypes.SelectedItem = type;
                    break;
                }
            }

            foreach (var constructorInfo in _constructorInfos)
            {
                if (constructorInfo.Name==_constructor.MethodName)
                {
                    if (constructorInfo.GetParameters().Length == _constructor.ParaTypes.Count)
                    {
                        lstMethod.SelectedItem = constructorInfo;
                        break;
                    }
                }
            }

            txtName.Text = _constructor.ItemName;

            #endregion

        }

        private void lstDll_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lstDll.SelectedItem==null) return;

            string fileName = Environment.CurrentDirectory + "\\" + lstDll.SelectedItem;
            _types = ReflectAble.GetTypes(fileName);
            BindingSource bs = new BindingSource();
            bs.DataSource = _types;
            lstTypes.DataSource = bs;
            lstTypes.DisplayMember = "Name";
        }

        private void lstTypes_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lstTypes.SelectedItem is Type  type)
            {
                _constructorInfos = type.GetConstructors();
                BindingSource bs = new BindingSource();
                bs.DataSource = _constructorInfos;
                lstMethod.DataSource = bs;
                _constructor.Description = $"{type.FullName}";
            }
        }

        private void lstMethod_SelectedIndexChanged(object sender, EventArgs e)
        {
            var ci = lstMethod.SelectedItem as ConstructorInfo;
            if (ci==null) return;

            var parameters = ci.GetParameters();
            _paraTypes.Clear();
            _paraNames.Clear();
            foreach (var parameterInfo in parameters)
            {
                _paraNames.Add(parameterInfo.Name);
                _paraTypes.Add(parameterInfo.ParameterType.FullName);
            }
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            RefreshDll(ckbLoadAll.Checked);
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (txtName.Text.Length==0)
            {
                ShowErrorDialog("请输入一个名称");
                return;
            }
            if (lstDll.SelectedItem == null) return;
            if (lstTypes.SelectedItem==null ) return;
            if (lstMethod.SelectedItem == null) return;
            _constructor.ItemName = txtName.Text;
            _constructor.Dll = lstDll.SelectedItem.ToString();
            _constructor.TypeName = (lstTypes.SelectedItem as Type)?.FullName;
            var ci = lstMethod.SelectedItem as ConstructorInfo;
            _constructor.MethodName = (ci)?.Name;
            _constructor.IsStatic = true;
            _constructor.Parms.Clear();
            _constructor.ParaNames.Clear();
            _constructor.ParaTypes.Clear();
            _constructor.ReturnType = typeof(object).FullName;
            _paraNames.ForEach(item=>_constructor.ParaNames.Add(item));
            _paraTypes.ForEach(item=>_constructor.ParaTypes.Add(item));
            for (int i = 0; i < _paraTypes.Count; i++)
            {
                _constructor.Parms.Add(new MethodParms(){Name = _paraNames[i],Type = _paraTypes[i]});
            }

            DialogResult = DialogResult.OK;
            Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }
    }
}
    